﻿using System;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;

namespace SoftSource.Common
{
    public static class AsyncOperationExtensions
    {
        public static bool IsInError(this AsyncCompletedEventArgs args)
        {
            if (args == null || args.Error != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static void EvaluateAsyncCompletion<T>(this IObserver<T> observer, AsyncCompletedEventArgs args, Func<T> expr)
        {
            if (args.IsInError())
            {
                observer.OnError(args.Error);
                return;
            }
            if (args.Cancelled)
            {
                observer.OnCompleted();
                return;
            }
            observer.OnNext(expr());
        }

        public static IObservable<TResult> SelectAsyncComputation<TArgs, TResult>(this IObservable<TArgs> observable, Func<TArgs, TResult> selector) where TArgs : AsyncCompletedEventArgs
        {
            return Observable.CreateWithDisposable<TResult>(observer =>
                observable.Subscribe(
                    args => observer.EvaluateAsyncCompletion(args, () => selector(args)),
                    observer.OnError,
                    observer.OnCompleted));
        }

        public static FaultException AsFaultException(this AsyncCompletedEventArgs args)
        {
            return args.Error.AsFaultException();
        }

        public static FaultException<T> AsFaultException<T>(this AsyncCompletedEventArgs args)
        {
            return args.Error.AsFaultException<T>();
        }
    }
}
